#include "FakeCameraConsumer.h"

using namespace android;

// Macros for including the GLConsumer name in log messages
#define LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
#define LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
//#define LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
#define LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
#define LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)

FakeCameraConsumer::FakeCameraConsumer(const sp<IGraphicBufferConsumer>& bq, bool isControlledByApp) :
    ConsumerBase(bq, isControlledByApp),
    mDefaultWidth(1),
    mDefaultHeight(1)
{
    mConsumer->setConsumerUsageBits(DEFAULT_USAGE_FLAGS);
}

status_t FakeCameraConsumer::setDefaultBufferSize(uint32_t w, uint32_t h)
{
    Mutex::Autolock lock(mMutex);
    if (mAbandoned) {
        LOGE("setDefaultBufferSize: FakeCameraConsumer is abandoned!");
        return NO_INIT;
    }
    mDefaultWidth = w;
    mDefaultHeight = h;
    return mConsumer->setDefaultBufferSize(w, h);
}

void FakeCameraConsumer::freeBufferLocked(int slotIndex) {
    LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
    ConsumerBase::freeBufferLocked(slotIndex);
}

void FakeCameraConsumer::abandonLocked() {
    LOGV("abandonLocked");
    ConsumerBase::abandonLocked();
}

void FakeCameraConsumer::dumpLocked(String8& result, const char* prefix) const
{
    ConsumerBase::dumpLocked(result, prefix);
}

status_t FakeCameraConsumer::acquireBufferLocked(BufferItem *item,
        nsecs_t presentWhen, uint64_t maxFrameNumber) {
    status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen,
            maxFrameNumber);
    if (err != NO_ERROR) {
        return err;
    }

    // If item->mGraphicBuffer is not null, this buffer has not been acquired
    // before, so any prior EglImage created is using a stale buffer. This
    // replaces any old EglImage with a new one (using the new buffer).
    if (item->mGraphicBuffer != nullptr) {
        int slot = item->mSlot;
        //mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer);
    }

    return NO_ERROR;
}

status_t FakeCameraConsumer::releaseBufferLocked(int buf,
        sp<GraphicBuffer> graphicBuffer,
        EGLDisplay display, EGLSyncKHR eglFence) {
    // release the buffer if it hasn't already been discarded by the
    // BufferQueue. This can happen, for example, when the producer of this
    // buffer has reallocated the original buffer slot after this buffer
    // was acquired.
    status_t err = ConsumerBase::releaseBufferLocked(
            buf, graphicBuffer, display, eglFence);
    //mEglSlots[buf].mEglFence = EGL_NO_SYNC_KHR;
    return err;
}

status_t FakeCameraConsumer::acquireBuffer(BufferItem *item, nsecs_t presentWhen, uint64_t maxFrameNumber)
{
    Mutex::Autolock lock(mMutex);

    status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen,
            maxFrameNumber);
    if (err != NO_ERROR) {
        return err;
    }

    // If item->mGraphicBuffer is not null, this buffer has not been acquired
    // before, so any prior EglImage created is using a stale buffer. This
    // replaces any old EglImage with a new one (using the new buffer).
    if (item->mGraphicBuffer != nullptr) {
        int slot = item->mSlot;
        //mEglSlots[slot].mEglImage = new EglImage(item->mGraphicBuffer);
    }

    return NO_ERROR;
}

status_t FakeCameraConsumer::releaseBuffer(int slot)
{
    Mutex::Autolock lock(mMutex);

    status_t err = ConsumerBase::releaseBufferLocked(
            slot, mSlots[slot].mGraphicBuffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);

    return err;
}

status_t FakeCameraConsumer::getGraphicBuffer(int slot, sp<GraphicBuffer> &graphicBuffer)
{
    graphicBuffer = mSlots[slot].mGraphicBuffer;
    return NO_ERROR;
}
